package com.pyp.kuaishou.service;

// import com.fasterxml.jackson.databind.ObjectMapper; // 已移除未使用
import com.pyp.kuaishou.model.Material;
import com.pyp.kuaishou.model.StorePlatformConfig;
import com.pyp.kuaishou.repository.MaterialRepository;
import com.pyp.kuaishou.repository.StorePlatformConfigRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import com.github.kwai.open.api.KwaiOpenVideoApi;
import com.github.kwai.open.request.StartUploadRequest;
import com.github.kwai.open.request.UploadFileRequest;
import com.github.kwai.open.request.VideoPublishRequest;
import com.github.kwai.open.response.StartUploadResponse;
import com.github.kwai.open.response.UploadFileResponse;
import com.github.kwai.open.response.VideoPublishResponse;
import com.github.kwai.open.KwaiOpenException;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.net.URI; // 新增: 用于构建请求URI
import java.net.http.HttpClient; // 新增: Java 11 HTTP客户端
import java.net.http.HttpRequest; // 新增: HTTP请求
import java.net.http.HttpResponse; // 新增: HTTP响应
import java.time.Duration; // 新增: 超时时间

/**
 * 作者: lauJinyu
 * 业务层：发布视频流程（读取DB素材与配置、上传、发布）
 * 已重构使用快手官方SDK替换RestTemplate
 */
@Service
@Slf4j
public class KSPublishService {

    private final StorePlatformConfigRepository configRepository;
    private final MaterialRepository materialRepository;
    private final AiCommentService aiCommentService;

    public KSPublishService(StorePlatformConfigRepository configRepository,
                            MaterialRepository materialRepository,
                            AiCommentService aiCommentService) {
        this.configRepository = configRepository;
        this.materialRepository = materialRepository;
        this.aiCommentService = aiCommentService;
    }

    /**
     * 发布视频到快手 - 完整流程
     * 作者: lauJinyu
     */
    public Map<String, Object> publishVideo(String accessToken, String appId) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 从数据库获取最新素材（根据app_id）
            Material material = materialRepository.findLatestByAppId(appId);

            if (material == null) {
                result.put("success", false);
                result.put("message", "未找到可发布的素材，appId: " + appId);
                return result;
            }
            
            // 立即更新素材使用统计（无论发布是否成功）
            try {
                materialRepository.updateMaterialUsage(material.getId());
                log.info("已更新素材使用统计，materialId: {}", material.getId());
            } catch (Exception e) {
                log.warn("更新素材使用统计失败，materialId: {}, error: {}", material.getId(), e.getMessage());
            }

            // 2. 验证access_token（从数据库获取配置）
            Optional<StorePlatformConfig> configOpt = configRepository.findByAppId(appId);
            if (!configOpt.isPresent()) {
                result.put("success", false);
                result.put("message", "未找到应用配置，appId: " + appId);
                return result;
            }

            // 确保API已初始化appId（每次请求使用独立实例避免并发状态污染）
            KwaiOpenVideoApi videoApi = KwaiOpenVideoApi.init(appId);

            // 3. 获取upload_token和endpoint (使用SDK)
            Map<String, Object> uploadTokenResult = getUploadToken(accessToken, videoApi);
            if (!(Boolean) uploadTokenResult.get("success")) {
                result.put("success", false);
                result.put("message", "获取upload_token失败: " + uploadTokenResult.get("message"));
                result.put("raw_response", uploadTokenResult.get("raw_response"));
                return result;
            }

            String uploadToken = (String) uploadTokenResult.get("upload_token");
            String endpoint = (String) uploadTokenResult.get("endpoint");

            // 4. 上传视频文件 (使用SDK)
            Map<String, Object> uploadResult = uploadVideo(uploadToken, endpoint, material.getFileUrl(), videoApi);
            if (!(Boolean) uploadResult.get("success")) {
                result.put("success", false);
                result.put("message", "视频上传失败: " + uploadResult.get("message"));
                result.put("raw_response", uploadResult.get("raw_response"));
                return result;
            }

            // 注意：SDK方式上传后不会直接返回video_id，而是在发布时使用upload_token
            // 5. 发布视频 (使用SDK)
            Map<String, Object> publishResult = publishVideoToKuaishou(accessToken, uploadToken, material, videoApi);

            if ((Boolean) publishResult.get("success")) {
                String photoId = (String) publishResult.get("photo_id");
                result.put("success", true);
                result.put("photo_id", photoId);
                result.put("message", "视频发布成功");
                result.put("app_id", appId);
                result.put("material_id", material.getId());
                result.put("file_url", material.getFileUrl());
                result.put("content", material.getContent());

                log.info("视频发布成功，appId: {}, materialId: {}, photoId: {}",
                        appId, material.getId(), photoId);
            } else {
                result.put("success", false);
                result.put("message", publishResult.get("message"));
                result.put("raw_response", publishResult.get("raw_response"));
                log.error("视频发布失败，appId: {}, materialId: {}, 错误: {}",
                        appId, material.getId(), publishResult.get("message"));
            }

        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "发布失败: " + e.getMessage());
            result.put("error_detail", e.getClass().getSimpleName());
            log.error("视频发布异常", e);
        }

        return result;
    }

    /**
     * 获取upload_token和endpoint (使用SDK)
     * 作者: lauJinyu
     */
    private Map<String, Object> getUploadToken(String accessToken, KwaiOpenVideoApi videoApi) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 使用SDK创建开始上传请求
            StartUploadRequest request = new StartUploadRequest();
            request.setAccessToken(accessToken);

            // 调用SDK方法获取上传信息
            StartUploadResponse response = videoApi.startUpload(request);

            if (response != null) {
                result.put("success", true);
                result.put("upload_token", response.getUploadToken());
                result.put("endpoint", response.getEndpoint());
                result.put("raw_response", response.toString());

                log.info("SDK获取upload_token成功: uploadToken={}, endpoint={}",
                        response.getUploadToken(), response.getEndpoint());

            } else {
                result.put("success", false);
                result.put("message", "SDK返回响应为空");
            }

        } catch (KwaiOpenException e) {
            result.put("success", false);
            result.put("message", "SDK获取upload_token失败: " + e.getMessage());
            result.put("error_code", e.getResult() != null ? e.getResult().getCode() : "unknown");
            log.error("SDK获取upload_token失败", e);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取upload_token异常: " + e.getMessage());
            log.error("获取upload_token异常", e);
        }

        return result;
    }

    /**
     * 通过HTTP/HTTPS下载远程资源为字节数组
     * 作者: lauJinyu
     */
    private byte[] fetchBytesFromUrl(String url) throws IOException, InterruptedException {
        HttpClient client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(15))
                .build();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(60))
                .GET()
                .build();
        HttpResponse<byte[]> resp = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
        int code = resp.statusCode();
        if (code >= 200 && code < 300) {
            return resp.body();
        }
        throw new IOException("下载失败, HTTP status=" + code + ", url=" + url);
    }

    /**
     * 上传视频文件到快手 (使用SDK)
     * 作者: lauJinyu
     */
    private Map<String, Object> uploadVideo(String uploadToken, String endpoint, String fileUrl, KwaiOpenVideoApi videoApi) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 读取文件数据，支持本地路径与网络URL
            byte[] fileData;

            if (fileUrl.startsWith("http://") || fileUrl.startsWith("https://")) {
                // 网络文件：通过HTTP下载
                fileData = fetchBytesFromUrl(fileUrl);
                log.info("已通过HTTP下载视频文件，大小: {} bytes", fileData != null ? fileData.length : -1);
            } else {
                // 本地文件
                fileData = Files.readAllBytes(Paths.get(fileUrl));
                log.info("已从本地读取视频文件，路径: {}，大小: {} bytes", fileUrl, fileData != null ? fileData.length : -1);
            }

            // 使用SDK创建上传请求
            UploadFileRequest request = new UploadFileRequest(uploadToken, endpoint, fileData);

            // 调用SDK方法上传文件
            UploadFileResponse response = videoApi.uploadFile(request);

            if (response != null) {
                result.put("success", true);
                result.put("raw_response", response.toString());

                log.info("SDK上传视频成功: {}", response.toString());

            } else {
                result.put("success", false);
                result.put("message", "SDK上传响应为空");
            }

        } catch (KwaiOpenException e) {
            result.put("success", false);
            result.put("message", "SDK上传视频失败: " + e.getMessage());
            result.put("error_code", e.getResult() != null ? e.getResult().getCode() : "unknown");
            log.error("SDK上传视频失败", e);
        } catch (IOException e) {
            result.put("success", false);
            result.put("message", "读取/下载文件异常: " + e.getMessage());
            log.error("读取/下载文件异常", e);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            result.put("success", false);
            result.put("message", "下载被中断: " + e.getMessage());
            log.error("下载被中断", e);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "上传视频异常: " + e.getMessage());
            log.error("上传视频异常", e);
        }

        return result;
    }

    /**
     * 发布视频到快手平台 (使用SDK)
     * 作者: lauJinyu
     */
    private Map<String, Object> publishVideoToKuaishou(String accessToken, String uploadToken, Material material, KwaiOpenVideoApi videoApi) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 记录发布前的关键参数用于调试
            log.info("开始发布视频到快手 - materialId: {}, uploadToken: {}, original_content: {}, coverUrl: {}", 
                    material.getId(), uploadToken, material.getContent(), material.getCoverUrl());
            
            // 使用AI生成视频标题
            String finalCaption = material.getContent(); // 默认使用原始内容作为fallback
            try {
                log.info("开始调用AI生成视频标题，原始内容: {}", material.getContent());
                Map<String, Object> aiResult = aiCommentService.generateCommentFromContent(material.getContent());
                
                if ((Boolean) aiResult.get("success")) {
                    String aiGeneratedContent = (String) aiResult.get("comment");
                    if (aiGeneratedContent != null && !aiGeneratedContent.trim().isEmpty()) {
                        // 对AI生成的内容进行字符长度限制（不超过12个字符）
                        finalCaption = aiCommentService.limitContentLength(aiGeneratedContent);
                        log.info("AI生成标题成功: 原始内容[{}] -> AI生成[{}] -> 最终标题[{}]", 
                                material.getContent(), aiGeneratedContent, finalCaption);
                    } else {
                        log.warn("AI生成的内容为空，使用原始内容作为标题");
                    }
                } else {
                    log.warn("AI生成标题失败: {}, 使用原始内容作为标题", aiResult.get("message"));
                }
                
                // 添加1-2秒延迟，避免模型响应延迟问题
                Thread.sleep(1500); // 1.5秒延迟
                log.info("AI处理完成，延迟1.5秒后继续发布流程");
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.warn("AI处理被中断，使用原始内容作为标题: {}", e.getMessage());
            } catch (Exception e) {
                log.error("AI生成标题异常，使用原始内容作为标题: {}", e.getMessage(), e);
            }
            
            // 使用SDK创建发布请求
            VideoPublishRequest request = new VideoPublishRequest();
            request.setAccessToken(accessToken);
            request.setUploadToken(uploadToken);
            request.setCaption(finalCaption); // 使用AI生成的标题或原始内容

            // 设置封面 (支持本地与网络)
            if (material.getCoverUrl() != null && !material.getCoverUrl().isEmpty()) {
                try {
                    byte[] coverData;
                    if (material.getCoverUrl().startsWith("http://") || material.getCoverUrl().startsWith("https://")) {
                        coverData = fetchBytesFromUrl(material.getCoverUrl());
                        log.info("已通过HTTP下载封面文件，大小: {} bytes", coverData != null ? coverData.length : -1);
                    } else {
                        coverData = Files.readAllBytes(Paths.get(material.getCoverUrl()));
                        log.info("已从本地读取封面文件，路径: {}，大小: {} bytes", material.getCoverUrl(), coverData != null ? coverData.length : -1);
                    }
                    request.setCover(coverData);
                } catch (Exception e) {
                    log.warn("读取/下载封面文件失败，将不设置封面: {}", e.getMessage());
                }
            }

            // 调用SDK方法发布视频
            log.debug("调用快手SDK发布视频，请求参数: {}", request.toString());
            VideoPublishResponse response = videoApi.videoPublish(request);

            if (response != null && response.getVideoInfo() != null) {
                result.put("success", true);
                result.put("photo_id", response.getVideoInfo().getPhotoId());
                result.put("raw_response", response.toString());

                log.info("SDK发布视频成功: photoId={}", response.getVideoInfo().getPhotoId());

            } else {
                result.put("success", false);
                result.put("message", "SDK发布响应为空或videoInfo为空");
                result.put("raw_response", response != null ? response.toString() : "null");
                log.error("SDK发布视频失败 - 响应为空或videoInfo为空，response: {}", response);
            }

        } catch (KwaiOpenException e) {
            result.put("success", false);
            result.put("message", "SDK发布视频失败: " + e.getMessage());
            
            // 增强错误信息收集
            if (e.getResult() != null) {
                result.put("error_code", e.getResult().getCode());
            } else {
                result.put("error_code", "unknown");
            }
            
            result.put("exception_type", "KwaiOpenException");
            result.put("raw_exception", e.toString());
            result.put("exception_message", e.getMessage());
            
            log.error("SDK发布视频失败 - materialId: {}, uploadToken: {}, error_code: {}, exception_message: {}", 
                    material.getId(), uploadToken, 
                    e.getResult() != null ? e.getResult().getCode() : "unknown",
                    e.getMessage(), e);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "发布视频异常: " + e.getMessage());
            result.put("exception_type", e.getClass().getSimpleName());
            result.put("raw_exception", e.toString());
            
            log.error("发布视频异常 - materialId: {}, uploadToken: {}, exception: {}", 
                    material.getId(), uploadToken, e.getClass().getSimpleName(), e);
        }

        return result;
    }
}